// META: title=test WebNN API element-wise erf operation
// META: global=window,dedicatedworker
// META: variant=?cpu
// META: variant=?gpu
// META: variant=?npu
// META: script=../resources/utils.js
// META: timeout=long

'use strict';

// https://www.w3.org/TR/webnn/#api-mlgraphbuilder-unary
// Compute the error function of the input tensor, element-wise.
//
// MLOperand erf(MLOperand input);


const getErfPrecisionTolerance = (graphResources) => {
  const toleranceValueDict = {float32: 1 / 1024, float16: 1 / 512};
  const expectedDataType =
      getExpectedDataTypeOfSingleOutput(graphResources.expectedOutputs);
  return {metricType: 'ATOL', value: toleranceValueDict[expectedDataType]};
};

const erfTests = [
  {
    'name': 'erf float32 0D scalar',
    'graph': {
      'inputs': {
        'erfInput': {
          'data': [-0.004352752584964037],
          'descriptor': {'dimensions': [], 'dataType': 'float32'}
        }
      },
      'operators': [{
        'name': 'erf',
        'arguments': [{'input': 'erfInput'}],
        'outputs': 'erfOutput'
      }],
      'expectedOutputs': {
        'erfOutput': {
          'data': [-0.004911554511636496],
          'descriptor': {'dimensions': [], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name': 'erf float32 1D constant tensor',
    'graph': {
      'inputs': {
        'erfInput': {
          'data': [
            -0.5883062481880188, -0.5323766469955444, 0.1279870569705963,
            0.5772181749343872,  0.904577910900116,   -0.49856746196746826,
            0.9843886494636536,  0.21642258763313293, 0.25235170125961304,
            -0.1491669863462448, 0.9136939644813538,  -0.5736439824104309,
            0.7404468059539795,  0.5202203392982483,  -0.16549505293369293,
            0.8005731701850891,  0.4001320004463196,  -0.7489422559738159,
            -0.8946002721786499, -0.3920256197452545, 0.6854220628738403,
            -0.6744900345802307, -0.439808189868927,  0.2709762454032898
          ],
          'descriptor': {'dimensions': [24], 'dataType': 'float32'},
          'constant': true
        }
      },
      'operators': [{
        'name': 'erf',
        'arguments': [{'input': 'erfInput'}],
        'outputs': 'erfOutput'
      }],
      'expectedOutputs': {
        'erfOutput': {
          'data': [
            -0.5945858955383301,  -0.5484867095947266,  0.14363321661949158,
            0.5856771469116211,   0.7991966009140015,   -0.5192402005195618,
            0.8361185789108276,   0.2404468059539795,   0.27881762385368347,
            -0.16707675158977509, 0.8036975860595703,   -0.5827808976173401,
            0.7049695253372192,   0.5380884408950806,   -0.1850501298904419,
            0.742441713809967,    0.4285193383693695,   -0.710474967956543,
            -0.7941843867301941,  -0.4207003712654114,  0.6676210165023804,
            -0.6598520874977112,  -0.46604686975479126, 0.29844197630882263
          ],
          'descriptor': {'dimensions': [24], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name': 'erf float32 1D tensor',
    'graph': {
      'inputs': {
        'erfInput': {
          'data': [
            -0.5883062481880188, -0.5323766469955444, 0.1279870569705963,
            0.5772181749343872,  0.904577910900116,   -0.49856746196746826,
            0.9843886494636536,  0.21642258763313293, 0.25235170125961304,
            -0.1491669863462448, 0.9136939644813538,  -0.5736439824104309,
            0.7404468059539795,  0.5202203392982483,  -0.16549505293369293,
            0.8005731701850891,  0.4001320004463196,  -0.7489422559738159,
            -0.8946002721786499, -0.3920256197452545, 0.6854220628738403,
            -0.6744900345802307, -0.439808189868927,  0.2709762454032898
          ],
          'descriptor': {'dimensions': [24], 'dataType': 'float32'}
        }
      },
      'operators': [{
        'name': 'erf',
        'arguments': [{'input': 'erfInput'}],
        'outputs': 'erfOutput'
      }],
      'expectedOutputs': {
        'erfOutput': {
          'data': [
            -0.5945858955383301,  -0.5484867095947266,  0.14363321661949158,
            0.5856771469116211,   0.7991966009140015,   -0.5192402005195618,
            0.8361185789108276,   0.2404468059539795,   0.27881762385368347,
            -0.16707675158977509, 0.8036975860595703,   -0.5827808976173401,
            0.7049695253372192,   0.5380884408950806,   -0.1850501298904419,
            0.742441713809967,    0.4285193383693695,   -0.710474967956543,
            -0.7941843867301941,  -0.4207003712654114,  0.6676210165023804,
            -0.6598520874977112,  -0.46604686975479126, 0.29844197630882263
          ],
          'descriptor': {'dimensions': [24], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name': 'erf float32 2D tensor',
    'graph': {
      'inputs': {
        'erfInput': {
          'data': [
            -0.5883062481880188, -0.5323766469955444, 0.1279870569705963,
            0.5772181749343872,  0.904577910900116,   -0.49856746196746826,
            0.9843886494636536,  0.21642258763313293, 0.25235170125961304,
            -0.1491669863462448, 0.9136939644813538,  -0.5736439824104309,
            0.7404468059539795,  0.5202203392982483,  -0.16549505293369293,
            0.8005731701850891,  0.4001320004463196,  -0.7489422559738159,
            -0.8946002721786499, -0.3920256197452545, 0.6854220628738403,
            -0.6744900345802307, -0.439808189868927,  0.2709762454032898
          ],
          'descriptor': {'dimensions': [4, 6], 'dataType': 'float32'}
        }
      },
      'operators': [{
        'name': 'erf',
        'arguments': [{'input': 'erfInput'}],
        'outputs': 'erfOutput'
      }],
      'expectedOutputs': {
        'erfOutput': {
          'data': [
            -0.5945858955383301,  -0.5484867095947266,  0.14363321661949158,
            0.5856771469116211,   0.7991966009140015,   -0.5192402005195618,
            0.8361185789108276,   0.2404468059539795,   0.27881762385368347,
            -0.16707675158977509, 0.8036975860595703,   -0.5827808976173401,
            0.7049695253372192,   0.5380884408950806,   -0.1850501298904419,
            0.742441713809967,    0.4285193383693695,   -0.710474967956543,
            -0.7941843867301941,  -0.4207003712654114,  0.6676210165023804,
            -0.6598520874977112,  -0.46604686975479126, 0.29844197630882263
          ],
          'descriptor': {'dimensions': [4, 6], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name': 'erf float32 3D tensor',
    'graph': {
      'inputs': {
        'erfInput': {
          'data': [
            -0.5883062481880188, -0.5323766469955444, 0.1279870569705963,
            0.5772181749343872,  0.904577910900116,   -0.49856746196746826,
            0.9843886494636536,  0.21642258763313293, 0.25235170125961304,
            -0.1491669863462448, 0.9136939644813538,  -0.5736439824104309,
            0.7404468059539795,  0.5202203392982483,  -0.16549505293369293,
            0.8005731701850891,  0.4001320004463196,  -0.7489422559738159,
            -0.8946002721786499, -0.3920256197452545, 0.6854220628738403,
            -0.6744900345802307, -0.439808189868927,  0.2709762454032898
          ],
          'descriptor': {'dimensions': [2, 3, 4], 'dataType': 'float32'}
        }
      },
      'operators': [{
        'name': 'erf',
        'arguments': [{'input': 'erfInput'}],
        'outputs': 'erfOutput'
      }],
      'expectedOutputs': {
        'erfOutput': {
          'data': [
            -0.5945858955383301,  -0.5484867095947266,  0.14363321661949158,
            0.5856771469116211,   0.7991966009140015,   -0.5192402005195618,
            0.8361185789108276,   0.2404468059539795,   0.27881762385368347,
            -0.16707675158977509, 0.8036975860595703,   -0.5827808976173401,
            0.7049695253372192,   0.5380884408950806,   -0.1850501298904419,
            0.742441713809967,    0.4285193383693695,   -0.710474967956543,
            -0.7941843867301941,  -0.4207003712654114,  0.6676210165023804,
            -0.6598520874977112,  -0.46604686975479126, 0.29844197630882263
          ],
          'descriptor': {'dimensions': [2, 3, 4], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name': 'erf float32 4D tensor',
    'graph': {
      'inputs': {
        'erfInput': {
          'data': [
            -0.5883062481880188, -0.5323766469955444, 0.1279870569705963,
            0.5772181749343872,  0.904577910900116,   -0.49856746196746826,
            0.9843886494636536,  0.21642258763313293, 0.25235170125961304,
            -0.1491669863462448, 0.9136939644813538,  -0.5736439824104309,
            0.7404468059539795,  0.5202203392982483,  -0.16549505293369293,
            0.8005731701850891,  0.4001320004463196,  -0.7489422559738159,
            -0.8946002721786499, -0.3920256197452545, 0.6854220628738403,
            -0.6744900345802307, -0.439808189868927,  0.2709762454032898
          ],
          'descriptor': {'dimensions': [2, 2, 2, 3], 'dataType': 'float32'}
        }
      },
      'operators': [{
        'name': 'erf',
        'arguments': [{'input': 'erfInput'}],
        'outputs': 'erfOutput'
      }],
      'expectedOutputs': {
        'erfOutput': {
          'data': [
            -0.5945858955383301,  -0.5484867095947266,  0.14363321661949158,
            0.5856771469116211,   0.7991966009140015,   -0.5192402005195618,
            0.8361185789108276,   0.2404468059539795,   0.27881762385368347,
            -0.16707675158977509, 0.8036975860595703,   -0.5827808976173401,
            0.7049695253372192,   0.5380884408950806,   -0.1850501298904419,
            0.742441713809967,    0.4285193383693695,   -0.710474967956543,
            -0.7941843867301941,  -0.4207003712654114,  0.6676210165023804,
            -0.6598520874977112,  -0.46604686975479126, 0.29844197630882263
          ],
          'descriptor': {'dimensions': [2, 2, 2, 3], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name': 'erf float32 5D tensor',
    'graph': {
      'inputs': {
        'erfInput': {
          'data': [
            -0.5883062481880188, -0.5323766469955444, 0.1279870569705963,
            0.5772181749343872,  0.904577910900116,   -0.49856746196746826,
            0.9843886494636536,  0.21642258763313293, 0.25235170125961304,
            -0.1491669863462448, 0.9136939644813538,  -0.5736439824104309,
            0.7404468059539795,  0.5202203392982483,  -0.16549505293369293,
            0.8005731701850891,  0.4001320004463196,  -0.7489422559738159,
            -0.8946002721786499, -0.3920256197452545, 0.6854220628738403,
            -0.6744900345802307, -0.439808189868927,  0.2709762454032898
          ],
          'descriptor': {'dimensions': [2, 1, 4, 1, 3], 'dataType': 'float32'}
        }
      },
      'operators': [{
        'name': 'erf',
        'arguments': [{'input': 'erfInput'}],
        'outputs': 'erfOutput'
      }],
      'expectedOutputs': {
        'erfOutput': {
          'data': [
            -0.5945858955383301,  -0.5484867095947266,  0.14363321661949158,
            0.5856771469116211,   0.7991966009140015,   -0.5192402005195618,
            0.8361185789108276,   0.2404468059539795,   0.27881762385368347,
            -0.16707675158977509, 0.8036975860595703,   -0.5827808976173401,
            0.7049695253372192,   0.5380884408950806,   -0.1850501298904419,
            0.742441713809967,    0.4285193383693695,   -0.710474967956543,
            -0.7941843867301941,  -0.4207003712654114,  0.6676210165023804,
            -0.6598520874977112,  -0.46604686975479126, 0.29844197630882263
          ],
          'descriptor': {'dimensions': [2, 1, 4, 1, 3], 'dataType': 'float32'}
        }
      }
    }
  }
];

if (navigator.ml) {
  erfTests.forEach((test) => {
    webnn_conformance_test(
        buildGraphAndCompute, getErfPrecisionTolerance, test);
  });
} else {
  test(() => assert_implements(navigator.ml, 'missing navigator.ml'));
}
